package com.amkai.aes.webservice.binary.objecthandler;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;

import com.amkai.aes.aescommon.service.binary.job.PeriodAndBatchJob;
import com.amkai.aes.aescommon.service.result.PeriodAndBatchJobResult;
import com.amkai.aes.generatedbeans.billinginterval.Batch;
import com.amkai.aes.generatedbeans.billinginterval.Expected;
import com.amkai.aes.generatedbeans.billinginterval.Period;
import com.amkai.aes.webservice.binary.JobObjectHandler;
import com.amkai.common.extensions.hibernate.config.SiteManager;
import com.amkai.common.extensions.hibernate.config.manager.SessionManager;
import com.amkai.extensions.server.services.IAoVersionManager;
import com.amkai.extensions.server.services.ServerServiceManager;

public class PeriodAndBatchJobHandler implements JobObjectHandler<PeriodAndBatchJob, Serializable, PeriodAndBatchJobResult> {
    @Override
    public PeriodAndBatchJobResult process(PeriodAndBatchJob job, Serializable object) throws Exception {
        PeriodAndBatchJobResult result = new PeriodAndBatchJobResult();
        
        SessionManager manager = SiteManager.Start();
        manager.openSession();
        try{
            switch(job.getKind()){
                case DOWNLOAD_PERIODS :
                    downloadPeriods(manager, job, result);
                    break;
                case DOWNLOAD_PERIOD :
                    downloadPeriod(manager, job, result);
                    break;
                case UPLOAD_PERIOD :
                    uploadPeriod(manager, job, result);
                    break;
                case UPLOAD_BATCH :
                    break;
            }
        }catch(Exception exception){            
            throw new Exception("Period and batch processing error", exception);
        }finally{
            manager.closeSession();
        }
        return result;
    }

    private final void updatePeriodsVersion(PeriodAndBatchJob job, PeriodAndBatchJobResult result) {
    	IAoVersionManager versionManager = ServerServiceManager.getInstance().getVersionManager();
    	String key = versionManager.getKey(IAoVersionManager.KEY_PERIOD, job.getModuleDepartment().getId());
        result.setPeriodsKey(key);
        result.setPeriodsVersion(versionManager.load(key));
    }
    
    @SuppressWarnings("unchecked")
    private void downloadPeriods(SessionManager manager, PeriodAndBatchJob job, PeriodAndBatchJobResult result) throws Exception{
        Query query = manager.execute("FROM Period period LEFT JOIN FETCH period.baseOrganization LEFT JOIN FETCH period.creator LEFT JOIN FETCH period.closer WHERE period.baseOrganization = :department");
        query.setParameter("department", job.getModuleDepartment());
        List<Period> periods = (List<Period>)query.list();
        if (periods!=null) {
            // AES-15934
            IAoVersionManager versionManager = ServerServiceManager.getInstance().getVersionManager();
        	for (Period period : periods) {
                String key = versionManager.getKey(IAoVersionManager.KEY_PERIOD, period.getBaseOrganization().getId());
                period.putTranzientProperty(key, versionManager.load(key));
        	}
        }
        result.setPeriods(periods);
        // AES-16210 - we load the general period version number
        updatePeriodsVersion(job, result);
    }
    
    private void downloadPeriod(SessionManager manager, PeriodAndBatchJob job, PeriodAndBatchJobResult result) throws Exception{
        Query query = manager.execute("FROM Period period LEFT JOIN FETCH period.baseOrganization LEFT JOIN FETCH period.creator LEFT JOIN FETCH period.closer LEFT JOIN FETCH period.batches WHERE period = :period");
        query.setParameter("period", job.getPeriod());
        
        Period period = (Period)query.uniqueResult();
        if(period != null){
            if(period.getBaseOrganization() != null){
                period.getBaseOrganization().getName();
            }
            if(period.getBatches() != null){
                for(Batch batch : period.getBatches()){
                    if(batch.getExpecteds() != null){
                        for(Expected expected : batch.getExpecteds()){
                            expected.getKind();
                        }
                    }
                    if(batch.getCreator() != null){
                        batch.getCreator().getName();
                    }
                    if(batch.getCloser() != null){;
                        batch.getCloser().getName();
                    }
                }
            }
            // AES-15934
            IAoVersionManager versionManager = ServerServiceManager.getInstance().getVersionManager();
            String key = versionManager.getKey(IAoVersionManager.KEY_PERIOD, period.getBaseOrganization().getId());
            period.putTranzientProperty(key, versionManager.load(key));
        }
        result.setPeriod(period);
    }
    
    private void uploadPeriod(SessionManager manager, PeriodAndBatchJob job, PeriodAndBatchJobResult result) throws Exception{
        Period period = job.getPeriod();
        // AES-15934 - try to change virtual version number of periods
        IAoVersionManager versionManager = ServerServiceManager.getInstance().getVersionManager();
        String key = versionManager.getKey(versionManager.KEY_PERIOD, period.getBaseOrganization().getId());
        Number version = (Number)period.getTranzientProperty(key);
        versionManager.update(key, version==null ? 0 : version.intValue());
        // it was an empty method, I have inserted bean version checking code (KokoG)
    }
}
